<script setup lang="ts">

import {ref, reactive, onMounted, onUnmounted, watch} from "vue";
import {ElNotification, FormInstance, FormRules, UploadProps, UploadRawFile} from "element-plus";
import axios from "axios";
import {ServerHost, loginUser} from "@/main.js";
import {v4 as uuidv4} from "uuid";
import {Plus} from "@element-plus/icons-vue";
import {downloadImg} from "@/utils";
import {createFilter} from "vite";
import AMapLoader from "@amap/amap-jsapi-loader";

// post or edit
const props = defineProps(['type', 'agritainment'])

let agritainment = reactive({
  id: "",
  name: "",
  img: "",
  introduction: "",
  contact: "",
  tel: "",
  address: "",
  posterId: "",
  lng: 110.296373, // 经度
  lat: 25.278333, // 纬度
  businessHours: "",
  addTime: new Date(),
});
const imgUrl = ref("")

let map = null
let marker = null
let AMap = null
let geocoder = null
onMounted(() => {
  AMapLoader.load({
    key: "225ab1a1758d7eed67798492e1c6263e",
    version: "2.0",
    plugins: [
      "AMap.Geolocation",
      "AMap.Geocoder"
    ],
  }).then((mAMap) => {
    AMap = mAMap;
    map = new AMap.Map('post-or-edit-map', {
      center: [agritainment.lng, agritainment.lat],
      zoom: 14,
    });

    // 定位到当前位置
    const geolocation = new AMap.Geolocation()
    geolocation.on('complete', (res: any) => {
      agritainment.lng = res.position.lng
      agritainment.lat = res.position.lat
      updateMarker(AMap, map)
      getAddress(geocoder)
    })
    map.addControl(geolocation);

    geocoder = new AMap.Geocoder();

    updateMarker(AMap, map)
    getAddress(geocoder)

    // 单击地图记录坐标
    map.on("click", (ev: any) => {
      const lnglat = ev.lnglat;
      agritainment.lng = lnglat.lng
      agritainment.lat = lnglat.lat
      updateMarker(AMap, map)
      getAddress(geocoder)
    });
  }).catch(e => {
    console.log(e);
  })
})

const updateMarker = (AMap: any, map: any) => {
  if (marker != null) {
    map.remove(marker)
  }
  marker = new AMap.Marker({
    position: [agritainment.lng, agritainment.lat],
  });
  map.add(marker); //添加到地图
}

const getAddress = (geocoder: any) => {
  geocoder.getAddress([agritainment.lng, agritainment.lat], (status, result) => {
    if (status === "complete" && result.info === "OK") {
      agritainment.address = result.regeocode.formattedAddress
    }
  });
}

onUnmounted(() => {
  map?.destroy();
});


// 监听经度
watch(() => agritainment.lng, (newValue, oldValue) => {
  map.setCenter([agritainment.lng, agritainment.lat])
  updateMarker(AMap, map)
  getAddress(geocoder)
});

// 监听纬度
watch(() => agritainment.lat, (newValue, oldValue) => {
  map.setCenter([agritainment.lng, agritainment.lat])
  updateMarker(AMap, map)
  getAddress(geocoder)
});

const isLoadingList = ref(false)
if (props.type === 'edit') {
  agritainment = props.agritainment
  agritainment.addTime = new Date(props.agritainment.addTime)
  // 下载封面
  if (props.agritainment.img) {
    isLoadingList.value = true
    downloadImg(props.agritainment.img, "agritainmentImg/")
        .then(res => {
          if (res.status === 200) {
            const type = props.agritainment.img.split('.')[1]
            let mime: string
            if ((['jpg', 'jpeg'] as any).includes('jpg'))
              mime = 'image/jpeg'
            else
              mime = `image/${type}`
            const blob = new Blob([res.data], {type: mime})
            imgFile = new File([blob], props.agritainment.img, {type: mime})
            imgUrl.value = URL.createObjectURL(imgFile)
            console.log(imgUrl.value)
            isLoadingList.value = false
          }
        })
  }

}

if (props.type === 'new') {
  // 每隔1s更新一次发布时间
  setInterval(() => {
    agritainment.addTime = new Date()
  }, 1000)
}

const agritainmentFormRef = ref<FormInstance>()

const validateIsNull = (rule: any, value: any, callback: any) => {
  let showName = "";
  switch (rule.field) {
    case "name":
      showName = "农家乐名称";
      break
    case "introduction":
      showName = "农家乐介绍";
      break
    case "contact":
      showName = "联系人"
      break
    case "tel":
      showName = "联系电话"
      break
    case "address":
      showName = "农家乐地址"
      break
    case "lng":
      showName = "位置经度"
      break
    case "lat":
      showName = "位置维度"
      break
    case "businessHours":
      showName = "营业时间"
      break
  }
  console.log(rule.field)
  if (!value) {
    callback(new Error(`请输入${showName}`))
  } else {
    callback()
  }
}

const agritainmentRules = ref<FormRules<typeof agritainment>>({
  name: [{validator: validateIsNull, trigger: 'blur'}],
  introduction: [{validator: validateIsNull, trigger: 'blur'}],
  contact: [{validator: validateIsNull, trigger: 'blur'}],
  tel: [{validator: validateIsNull, trigger: 'blur'}],
  address: [{validator: validateIsNull, trigger: 'blur'}],
  lng: [{validator: validateIsNull, trigger: 'blur'}],
  lat: [{validator: validateIsNull, trigger: 'blur'}],
  businessHours: [{validator: validateIsNull, trigger: 'blur'}],
})

let imgFile: File

const verifyImg = (rawFile: UploadRawFile) => {
  return !(rawFile.size > 1024 * 1024)
}

const isChangeImg = ref(false)
const onAddImg: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {

  if (!verifyImg(rawFile)) {
    ElNotification({
      title: '图片大小不能超过1MB',
      type: 'warning',
      position: 'bottom-right',
    })
    return
  }

  console.log(rawFile)
  imgFile = rawFile
  imgUrl.value = URL.createObjectURL(rawFile)

  if (props.type === 'edit') {
    isChangeImg.value = true
  }

}

const onPostNewAgritainment = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {

      //有封面则传封面
      agritainment.img = uploadImg().toString()

      // 生成uuid
      agritainment.id = uuidv4()
      agritainment.posterId = loginUser.value.id


      console.log('start submit!')
      console.log(agritainment)
      axios.post(`${ServerHost}/postNewAgritainment`, agritainment)
          .then((res) => {
            if (res.status === 200) {
              // 清空内容
              agritainment.name = ""
              agritainment.introduction = ""
              agritainment.contact = ""
              agritainment.tel = ""
              agritainment.businessHours = ""
              imgUrl.value = ""
              imgFile = undefined
              ElNotification({
                title: '农家乐发布成功',
                type: 'success',
                position: 'bottom-right',
              })
            } else {
              ElNotification({
                title: '农家乐发布失败',
                type: 'error',
                position: 'bottom-right',
              })
            }
          })
    } else {
      console.log('error submit!')
    }
  })
}

const emit = defineEmits(["getValue"])

const onUpdateAgritainment = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {

      //有封面改动则传封面
      if (isChangeImg.value) {
        agritainment.img = uploadImg().toString()
      }

      console.log(agritainment)
      console.log('start submit!')
      axios.post(`${ServerHost}/updateAgritainment`, agritainment)
          .then((res) => {
            if (res.status === 200) {
              emit("getValue", true)
              ElNotification({
                title: '农家乐修改成功',
                type: 'success',
                position: 'bottom-right',
              })
            } else {
              ElNotification({
                title: '农家乐修改失败',
                type: 'error',
                position: 'bottom-right',
              })
            }
          })


    } else {
      console.log('error submit!')
    }

  })
}

// 覆盖自带的上传行为
const onImgUpload = () => {
  console.log('onImgUpload')
}

const uploadImg = (): String => {
  let fileName = ""
  console.log(imgFile)
  if (!(typeof imgFile === "undefined")) {
    fileName += uuidv4()
    const fileFormat = imgFile.type.split("/")[1]
    fileName += '.' + fileFormat

    axios.post(`${ServerHost}/postFile`, {file: imgFile}, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
      params: {
        "name": fileName,
        "path": "agritainmentImg/"
      }
    })
        .then(res => {
          if (res.status === 200) {
            ElNotification({
              title: '图片上传成功',
              type: 'success',
              position: 'bottom-right',
            })
          } else {
            ElNotification({
              title: '图片上传失败',
              type: 'error',
              position: 'bottom-right',
            })
          }
        })
    return fileName
  } else {
    return ""
  }
}

const onDeleteAgritainment = () => {
  console.log(agritainment.id)
  axios.post(`${ServerHost}/deleteAgritainment?id=${agritainment.id}`,)
      .then(res => {
        if (res.status === 200) {
          emit("getValue", true)
          ElNotification({
            title: '商品删除成功',
            type: 'success',
            position: 'bottom-right',
          })
        } else {
          ElNotification({
            title: '商品删除失败',
            type: 'success',
            position: 'bottom-right',
          })
        }
      })
}

const querySearchType = (queryString: string, cb: any) => {
  const results = goodTypeList.value.filter((type: { value: "" }) => {
    return type.value.includes(queryString);
  })
  cb(results)
}

</script>

<template>

  <el-form ref="agritainmentFormRef" :rules="agritainmentRules" :model="agritainment">

    <el-form-item label="农家乐展示图" prop="title">
      <div class="goods-img-upload">
        <el-upload
            drag
            class=""
            :http-request="onImgUpload"
            :before-upload="onAddImg"
            :show-file-list="false"
            v-loading="isLoadingList"
        >
          <el-image v-if="imgUrl" fit="contain" :src="imgUrl" class="goods-img"
                    alt="Goods Img"/>
          <el-icon v-else class="img-uploader-icon">
            <Plus/>
          </el-icon>
        </el-upload>
      </div>
    </el-form-item>

    <el-form-item label="农家乐位置">
      <div class="border" id="post-or-edit-map"/>
      <div class="flex  w-full justify-between gap-4 mt-2">
        <el-form-item label="经度" prop="lng">
          <el-input-number v-model="agritainment.lng" :controls="false" style="width: 130px"></el-input-number>
        </el-form-item>
        <el-form-item label="维度" prop="lat">
          <el-input-number v-model="agritainment.lat" :controls="false" style="width: 130px"></el-input-number>
        </el-form-item>
      </div>
      <div class="flex gap-2 w-full mt-4">
        <el-form-item class="w-full" label="地址" prop="address">
          <el-input v-model="agritainment.address" placeholder="请输入农家乐地址" type="textarea" autosize></el-input>
        </el-form-item>
      </div>
    </el-form-item>

    <el-form-item label="农家乐名称" prop="name">
      <el-input v-model="agritainment.name" placeholder="请输入农家乐名称"></el-input>
    </el-form-item>

    <el-form-item label="农家乐介绍" prop="introduction">
      <el-input v-model="agritainment.introduction" type="textarea" :rows="10"
                placeholder="请输入农家乐介绍"></el-input>
    </el-form-item>

    <el-form-item label="联系人" prop="contact">
      <el-input v-model="agritainment.contact" placeholder="请输入联系人"></el-input>
    </el-form-item>

    <el-form-item label="联系电话" prop="tel">
      <el-input v-model="agritainment.tel" placeholder="请输入联系电话"></el-input>
    </el-form-item>

    <el-form-item label="营业时间" prop="businessHours">
      <el-input v-model="agritainment.businessHours" placeholder="请输入营业时间"></el-input>
    </el-form-item>

    <el-form-item label="添加时间">
      <el-date-picker
          v-model="agritainment.addTime"
          type="datetime"
          :readonly="true"/>
    </el-form-item>

    <el-form-item>
      <el-button v-if="props.type === 'new'" type="primary" @click="onPostNewAgritainment(agritainmentFormRef)">发布
      </el-button>
      <el-button v-if="props.type === 'edit'" type="primary" @click="onUpdateAgritainment(agritainmentFormRef)">
        确认修改
      </el-button>
      <el-popconfirm
          v-if="props.type === 'edit'"
          width="auto"
          title="确定要删除吗"
          confirm-button-text="确认删除"
          confirm-button-type="danger"
          cancel-button-text="取消"
          placement="top"
          @confirm="onDeleteAgritainment"
      >
        <template #reference>
          <el-button type="danger">删除</el-button>
        </template>
      </el-popconfirm>
    </el-form-item>
  </el-form>
</template>

<style scoped lang="scss">

$img-img-size: 200px;

.goods-img-upload {
  width: $img-img-size;
  height: $img-img-size;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
}

.goods-img-upload:hover {
  border-color: var(--el-color-primary);
}

.goods-img, .img-uploader-icon {
  width: $img-img-size;
  height: $img-img-size;
}

#post-or-edit-map {
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 4px;
}

</style>
